package com.spottydog.virtues;

import java.util.Date;
import java.util.SortedMap;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.view.View;

public class VirtueChart extends View {

	private SortedMap<Date, Integer> chartData;
	private Paint paint;
	
	public VirtueChart(Context context) {
		super(context);
		setFocusable(false);
		
		this.paint = new Paint();
		this.paint.setColor(Color.BLACK);
		this.paint.setAntiAlias(true);
		this.paint.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/BenjaminFranklin.ttf"));
		this.paint.setTextSize(10f);
	}
	
	public void setChartData(SortedMap<Date, Integer> chartData) {
		this.chartData = chartData;
	}

	@Override
	public void onDraw(Canvas canvas) {
		
		Date lowerDate = null;
		Date upperDate = null;
		int lowerCount = -1;
		int upperCount = 1;
		
		for (Date d : this.chartData.keySet()) {
			if (lowerDate == null || d.before(lowerDate)) lowerDate = d;
			if (upperDate == null || d.after(upperDate)) upperDate = d;
			if (this.chartData.get(d) < lowerCount) lowerCount = this.chartData.get(d);
			if (this.chartData.get(d) > upperCount) upperCount = this.chartData.get(d);
		}
				
		int startX = 20;
		int endX = this.getWidth();
		
		int startY = 5;
		int endY = this.getHeight() - 5;
				
		int pixPerCount = (endY-startY)/(upperCount+(-1*lowerCount)); // lowerCount is guaranteed 0 or -ve
		int zeroY = endY - (-1*lowerCount*pixPerCount);
		
		canvas.drawLine(startX, zeroY, endX, zeroY, this.paint);
		canvas.drawLine(startX, startY, startX, endY, this.paint);
		
		// Up to 12 ticks: display all
		// Up to 24 ticks: every second
		// Up to 36 ticks: every third etc. etc.
		int tickResolution = ((upperCount+(-1*lowerCount))/12)+1;
		
		// Start ticks on zero line and go in each direction looks better when there are
		// pixel rounding issues
		for (int i = 0; i <= upperCount; i=i+tickResolution) {
			drawYAxisTick(canvas, i, startX, zeroY-(i*pixPerCount));
		}		
		if (lowerCount != 0) for (int i = 0-tickResolution; i >= lowerCount; i=i-tickResolution) {
			drawYAxisTick(canvas, i, startX, zeroY-(i*pixPerCount));
		}
				
		// Calculate pixels per day
		int pixPerDay = (endX-startX)/this.chartData.keySet().size();
		
		// For each day, draw a box ppd wide (small pad each side) and count*ppc high
		int i = 0;
		this.paint.setStrokeWidth(pixPerDay*0.9f);

		for (Date d : this.chartData.keySet()) {
			int count = this.chartData.get(d);

			float left = startX+(i*pixPerDay)+(0.95f*pixPerDay);
			float top = 0f;
			float bottom = 0f;
			if (count >= 0) {
				top = zeroY-count*pixPerCount;
				bottom = zeroY;
			}
			else {
				top = zeroY;
				bottom = zeroY-count*pixPerCount;				
			}

			//this.paint.setStyle(Paint.Style.FILL_AND_STROKE);
			//RectF r = new RectF(left, top, right, bottom);
			//canvas.drawRoundRect(r, 0f, 0f, this.paint);
			canvas.drawLine(left, bottom, left, top, this.paint);
			i++;
		}
		this.paint.setStrokeWidth(1);
	}
	
	private void drawYAxisTick(Canvas canvas, int num, int x, int y) {
		this.paint.setTextAlign(Align.RIGHT);
		canvas.drawText(String.valueOf(num), x-10, y, this.paint);
	}
}
